libxl: Fix libxl_postfork_child_noexec deadlock etc.
authorIan Jackson <ian.jackson@eu.citrix.com>
Mon, 24 Feb 2014 12:57:53 +0000 (12:57 +0000)
committerIan Jackson <Ian.Jackson@eu.citrix.com>
Mon, 24 Feb 2014 16:30:23 +0000 (16:30 +0000)
commitd6ac84ca0db28b99073d4364815e0f71600c5780
tree790661d7cc7687072c672b8030775a73eb802e3a
parent9b51591c330672765d866a5ed4ed8e40c75bb1cf
libxl: Fix libxl_postfork_child_noexec deadlock etc.

libxl_postfork_child_noexec would nestedly reaquire the non-recursive
"no_forking" mutex: atfork_lock uses it, as does sigchld_user_remove.
The result on Linux is that the process always deadlocks before
returning from this function.

This is used by xl's console child.  So, the ultimate effect is that
xl with pygrub does not manage to connect to the pygrub console.
This behaviour was reported by Michael Young in Xen 4.4.0 RC5.

Also, the use of sigchld_user_remove in libxl_postfork_child_noexec is
not correct with SIGCHLD sharing.  libxl_postfork_child_noexec is
documented to suffice if called only on one ctx.  So deregistering the
ctx it's called on is not sufficient.  Instead, we need a new approach
which discards the whole sigchld_user list and unconditionally removes
our SIGCHLD handler if we had one.

Prompted by this, clarify the semantics of
libxl_postfork_child_noexec.  Specifically, expand on the meaning of
"quickly" by explaining what operations are not permitted; and
document the fact that the function doesn't reclaim the resources in
the ctxs.

And add a comment in libxl_postfork_child_noexec explaining the
internal concurrency situation.

This is an important bugfix.  IMO the bug is a blocker for Xen 4.4.

Signed-off-by: Ian Jackson <Ian.Jackson@eu.citrix.com>
Reported-by: M A Young <m.a.young@durham.ac.uk>
CC: Ian Campbell <Ian.Campbell@citrix.com>
CC: George Dunlap <george.dunlap@eu.citrix.com>
Acked-by: Ian Campbell <Ian.Campbell@citrix.com>
Release-acked-by: George Dunlap <george.dunlap@eu.citrix.com>
(cherry picked from commit 5be1e95318147855713709094e6847e3104ae910)
tools/libxl/libxl_event.h
tools/libxl/libxl_fork.c